'use strict';
const nodePath = require('path');
const fs = require('fs-extra');
const id3Writer = require('browser-id3-writer');
const Metaflac = require('metaflac-js2');
const { capitalizeFirstLetter, ensureDir } = require('../utils');
const log = require('../logger');

const afterLyricsFetching = (decryptedTrackBuffer, trackInfos, albumInfos, saveFilePath, coverBuffer) => {
  return new Promise((resolve, reject) => {
    let trackMetadata = {
      title: trackInfos.SNG_TITLE_VERSION,
      album: trackInfos.ALB_TITLE,
      // link: trackInfos.ALB_ID,
      releaseType: '',
      genre: '',
      artists: [],
      albumArtist: trackInfos.ALB_ART_NAME,
      trackNumber: trackInfos.TRACK_POSITION,
      trackNumberCombined: trackInfos.TRACK_POSITION ? trackInfos.TRACK_POSITION + '/' + albumInfos.NUMBER_TRACK : '',
      partOfSet: trackInfos.DISK_NUMBER,
      partOfSetCombined: trackInfos.DISK_NUMBER,
      label: albumInfos.LABEL,
      copyright: '',
      composer: [],
      publisher: [],
      producer: [],
      engineer: [],
      writer: [],
      author: [],
      mixer: [],
      ISRC: trackInfos.ISRC,
      duration: trackInfos.DURATION,
      bpm: trackInfos.BPM,
      upc: albumInfos.UPC,
      explicit: trackInfos.EXPLICIT_LYRICS,
      tracktotal: albumInfos.NUMBER_TRACK,
      disctotal: albumInfos.NUMBER_DISK,
      compilation: '',
      unsynchronisedLyrics: '',
      synchronisedLyrics: '',
      media: 'Digital Media',
      releaseYear: '',
      releaseDate: '',
    };

    if (trackInfos.ALB_RELEASE_TYPE) {
      let releaseType = trackInfos.ALB_RELEASE_TYPE;

      if ('ep' === releaseType) {
        releaseType = 'EP';
      } else {
        releaseType = capitalizeFirstLetter(releaseType);
      }

      trackMetadata.releaseType = releaseType;
    }

    if (albumInfos.GENRES && albumInfos.GENRES[0]) {
      trackMetadata.genre = albumInfos.GENRES[0];
    }

    // set date and year for tracks
    let releaseDate =
      trackInfos.ALB_RELEASE_DATE || trackInfos.PHYSICAL_RELEASE_DATE || trackInfos.DIGITAL_RELEASE_DATE;

    if (releaseDate) {
      trackMetadata.releaseYear = releaseDate.slice(0, 4);
      trackMetadata.releaseDate = releaseDate.slice(0, 10);
    }

    if (trackInfos.COPYRIGHT) {
      trackMetadata.copyright = trackInfos.COPYRIGHT;
    }

    if (trackInfos.ARTISTS) {
      let trackArtists = [];

      trackInfos.ARTISTS.forEach((trackArtist) => {
        if (trackArtist.ART_NAME) {
          trackArtist = trackArtist.ART_NAME.split(
            new RegExp(' featuring | feat. | Ft. | ft. | vs | vs. | x | - |, ', 'g')
          );
          trackArtist = trackArtist.map(Function.prototype.call, String.prototype.trim);

          trackArtists = trackArtists.concat(trackArtist);
        }
      });

      trackArtists = [...new Set(trackArtists)];
      trackMetadata.artists = trackArtists;
    }

    if (albumInfos.PRODUCER_LINE) {
      trackMetadata.publisher = [albumInfos.PRODUCER_LINE];
    }

    if (trackInfos.SNG_CONTRIBUTORS) {
      if (trackInfos.SNG_CONTRIBUTORS.composer) {
        trackMetadata.composer = trackInfos.SNG_CONTRIBUTORS.composer;
      }

      if (trackInfos.SNG_CONTRIBUTORS.musicpublisher) {
        trackMetadata.publisher = trackInfos.SNG_CONTRIBUTORS.musicpublisher;
      }

      if (trackInfos.SNG_CONTRIBUTORS.producer) {
        trackMetadata.producer = trackInfos.SNG_CONTRIBUTORS.producer;
      }

      if (trackInfos.SNG_CONTRIBUTORS.engineer) {
        trackMetadata.engineer = trackInfos.SNG_CONTRIBUTORS.engineer;
      }

      if (trackInfos.SNG_CONTRIBUTORS.writer) {
        trackMetadata.writer = trackInfos.SNG_CONTRIBUTORS.writer;
      }

      if (trackInfos.SNG_CONTRIBUTORS.author) {
        trackMetadata.author = trackInfos.SNG_CONTRIBUTORS.author;
      }

      if (trackInfos.SNG_CONTRIBUTORS.mixer) {
        trackMetadata.mixer = trackInfos.SNG_CONTRIBUTORS.mixer;
      }
    }

    if (trackInfos.ALB_ART_NAME === 'Various Artists') {
      trackMetadata.compilation = 1;
    } else {
      trackMetadata.compilation = 0;
    }

    if (trackInfos.LYRICS) {
      if (trackInfos.LYRICS.LYRICS_TEXT) {
        trackMetadata.unsynchronisedLyrics = trackInfos.LYRICS.LYRICS_TEXT;
      }

      if (trackInfos.LYRICS.LYRICS_SYNC_JSON) {
        const syncedLyrics = trackInfos.LYRICS.LYRICS_SYNC_JSON;

        for (let i = 0; i < syncedLyrics.length; i++) {
          if (syncedLyrics[i].lrc_timestamp) {
            trackMetadata.synchronisedLyrics += syncedLyrics[i].lrc_timestamp + syncedLyrics[i].line + '\r\n';
          } else if (i + 1 < syncedLyrics.length) {
            trackMetadata.synchronisedLyrics += syncedLyrics[i + 1].lrc_timestamp + syncedLyrics[i].line + '\r\n';
          }
        }
      }
    }

    let saveFilePathExtension = nodePath.extname(saveFilePath);

    if (saveFilePathExtension === '.mp3') {
      log.debug('Started MP3 tagging "track/' + trackInfos.SNG_ID + '"');

      const writer = new id3Writer(decryptedTrackBuffer);
      writer
        .setFrame('TIT2', trackMetadata.title)
        .setFrame('TALB', trackMetadata.album)
        .setFrame('TCON', [trackMetadata.genre])
        .setFrame('TPE2', trackMetadata.albumArtist)
        .setFrame('TPE1', [trackMetadata.artists.join(', ')])
        .setFrame('TCOP', trackMetadata.copyright)
        .setFrame('TPUB', trackMetadata.publisher.join(', '))
        .setFrame('TMED', trackMetadata.media)
        .setFrame('TXXX', {
          description: 'Artists',
          value: trackMetadata.artists.join(', '),
        })
        .setFrame('TXXX', {
          description: 'RELEASETYPE',
          value: trackMetadata.releaseType,
        })
        .setFrame('TXXX', {
          description: 'ISRC',
          value: trackMetadata.ISRC,
        })
        .setFrame('TXXX', {
          description: 'BARCODE',
          value: trackMetadata.upc,
        })
        .setFrame('TXXX', {
          description: 'LABEL',
          value: trackMetadata.label,
        })
        .setFrame('TXXX', {
          description: 'COMPILATION',
          value: trackMetadata.compilation,
        })
        .setFrame('TXXX', {
          description: 'SOURCE',
          value: 'Deezer',
        })
        .setFrame('TXXX', {
          description: 'SOURCEID',
          value: trackInfos.SNG_ID,
        });

      if (trackMetadata.partOfSet) {
        writer.setFrame('TXXX', {
          description: 'DISCNUMBER',
          value: trackMetadata.partOfSet,
        });
      }

      if (trackMetadata.disctotal) {
        writer.setFrame('TXXX', {
          description: 'DISCTOTAL',
          value: trackMetadata.disctotal,
        });
        writer.setFrame('TXXX', {
          description: 'TOTALDISCS',
          value: trackMetadata.disctotal,
        });
      }

      if (trackMetadata.duration) {
        writer.setFrame('TXXX', {
          description: 'LENGTH',
          value: trackMetadata.duration,
        });
      }

      if (trackMetadata.composer.length > 0) {
        writer.setFrame('TXXX', {
          description: 'COMPOSER',
          value: trackMetadata.composer.join(', '),
        });
      }

      if (trackMetadata.partOfSetCombined) {
        writer.setFrame('TPOS', trackMetadata.partOfSetCombined);
      }

      if (trackMetadata.trackNumberCombined) {
        writer.setFrame('TRCK', trackMetadata.trackNumberCombined);
      }

      if (trackMetadata.writer > 0) {
        writer.setFrame('TXXX', {
          description: 'LYRICIST',
          value: trackMetadata.writer.join(', '),
        });
      }

      if (trackMetadata.mixer.length > 0) {
        writer.setFrame('TXXX', {
          description: 'MIXARTIST',
          value: trackMetadata.mixer.join(', '),
        });
      }

      if (trackMetadata.producer.length > 0) {
        writer.setFrame('TXXX', {
          description: 'INVOLVEDPEOPLE',
          value: trackMetadata.producer.concat(trackMetadata.engineer).join(', '),
        });
      }

      if (trackMetadata.explicit) {
        writer.setFrame('TXXX', {
          description: 'EXPLICIT',
          value: trackMetadata.explicit,
        });
      }

      if (trackMetadata.unsynchronisedLyrics) {
        writer.setFrame('USLT', {
          description: '',
          lyrics: trackMetadata.unsynchronisedLyrics,
        });
      }

      if (trackMetadata.link) {
        writer.setFrame('TXXX', {
          description: 'LINK',
          value: 'https://www.deezer.com/album/' + trackMetadata.link,
        });
      }

      if (coverBuffer) {
        writer.setFrame('APIC', {
          type: 3,
          data: coverBuffer,
          description: '',
        });
      }

      if (trackMetadata.releaseYear) {
        writer.setFrame('TYER', trackMetadata.releaseYear);
      }

      if (trackMetadata.releaseDate) {
        writer.setFrame('TDAT', trackMetadata.releaseDate);
      }

      if (trackMetadata.bpm) {
        writer.setFrame('TBPM', trackMetadata.bpm);
      }

      writer.addTag();

      ensureDir(saveFilePath);
      fs.writeFileSync(saveFilePath, Buffer.from(writer.arrayBuffer));

      log.debug('Finished MP3 tagging "track/' + trackInfos.SNG_ID + '"');

      resolve({ path: saveFilePath });
    } else if (saveFilePathExtension === '.flac') {
      log.debug('Started FLAC tagging "track/' + trackInfos.SNG_ID + '"');

      const flac = new Metaflac(decryptedTrackBuffer);

      if (trackMetadata.title) {
        flac.setTag('TITLE=' + trackMetadata.title);
      }

      if (trackMetadata.album) {
        flac.setTag('ALBUM=' + trackMetadata.album);
      }

      if (trackMetadata.genre) {
        flac.setTag('GENRE=' + trackMetadata.genre);
      }

      if (trackMetadata.albumArtist) {
        flac.setTag('ALBUMARTIST=' + trackMetadata.albumArtist);
      }

      if (trackMetadata.artists.length > 0) {
        flac.setTag('ARTIST=' + trackMetadata.artists.join(', '));
      }

      if (trackMetadata.trackNumber) {
        flac.setTag('TRACKNUMBER=' + trackMetadata.trackNumber);
      }

      if (trackMetadata.tracktotal) {
        flac.setTag('TRACKTOTAL=' + trackMetadata.tracktotal);
        flac.setTag('TOTALTRACKS=' + trackMetadata.tracktotal);
      }

      if (trackMetadata.partOfSet) {
        flac.setTag('DISCNUMBER=' + trackMetadata.partOfSet);
      }

      if (trackMetadata.disctotal) {
        flac.setTag('DISCTOTAL=' + trackMetadata.disctotal);
        flac.setTag('TOTALDISCS=' + trackMetadata.disctotal);
      }

      if (trackMetadata.label) {
        flac.setTag('LABEL=' + trackMetadata.label);
      }

      if (trackMetadata.copyright) {
        flac.setTag('COPYRIGHT=' + trackMetadata.copyright);
      }

      if (trackMetadata.duration) {
        flac.setTag('LENGTH=' + trackMetadata.duration);
      }

      if (trackMetadata.ISRC) {
        flac.setTag('ISRC=' + trackMetadata.ISRC);
      }

      if (trackMetadata.upc) {
        flac.setTag('BARCODE=' + trackMetadata.upc);
      }

      if (trackMetadata.media) {
        flac.setTag('MEDIA=' + trackMetadata.media);
      }

      if (trackMetadata.compilation) {
        flac.setTag('COMPILATION=' + trackMetadata.compilation);
      }

      if (trackMetadata.explicit) {
        flac.setTag('EXPLICIT=' + trackMetadata.explicit);
      }

      if (trackMetadata.releaseType) {
        flac.setTag('RELEASETYPE=' + trackMetadata.releaseType);
      }

      if (trackMetadata.artists.length > 0) {
        flac.setTag('ARTISTS=' + trackMetadata.artists.join(', '));
      }

      if (trackMetadata.composer.length > 0) {
        flac.setTag('COMPOSER=' + trackMetadata.composer.join(', '));
      }

      if (trackMetadata.publisher.length > 0) {
        flac.setTag('ORGANIZATION=' + trackMetadata.publisher.join(', '));
      }

      if (trackMetadata.producer.length > 0) {
        flac.setTag('PRODUCER=' + trackMetadata.producer.concat(trackMetadata.engineer).join(', '));
      }

      if (trackMetadata.engineer.length > 0) {
        flac.setTag('ENGINEER=' + trackMetadata.engineer.join(', '));
      }

      if (trackMetadata.writer.length > 0) {
        flac.setTag('WRITER=' + trackMetadata.writer.join(', '));
      }

      if (trackMetadata.author) {
        flac.setTag('AUTHOR=' + trackMetadata.author.join(', '));
      }

      if (trackMetadata.mixer.length > 0) {
        flac.setTag('MIXER=' + trackMetadata.mixer.join(', '));
      }

      if (trackMetadata.unsynchronisedLyrics) {
        flac.setTag('LYRICS=' + trackMetadata.unsynchronisedLyrics);
      }

      if (trackMetadata.releaseYear) {
        flac.setTag('YEAR=' + trackMetadata.releaseYear);
      }

      if (trackMetadata.releaseDate) {
        flac.setTag('DATE=' + trackMetadata.releaseDate);
      }

      if (trackMetadata.bpm) {
        flac.setTag('BPM=' + trackMetadata.bpm);
      }

      if (trackMetadata.link) {
        flac.setTag('LINK=https://www.deezer.com/album/' + trackMetadata.link);
      }

      if (coverBuffer) {
        flac.importPicture(coverBuffer);
      }

      flac.setTag('SOURCE=Deezer');
      flac.setTag('SOURCEID=' + trackInfos.SNG_ID);

      ensureDir(saveFilePath);
      fs.writeFileSync(saveFilePath, Buffer.from(flac.save()));

      resolve({ path: saveFilePath });
    }
  });
};

module.exports = afterLyricsFetching;
